# -*- coding: utf-8 -*-
"""
乒乓球培训管理系统 - 师生关系控制器

师生关系管理的业务逻辑层
包括申请、审核、关系管理等功能
"""

from flask import current_app
from sqlalchemy import and_, or_, func, desc, asc
from datetime import datetime, timedelta
from decimal import Decimal

from app.models import db
from app.models.user import User
from app.models.relation import StudentCoachRelation
from app.models.campus import Campus
from app.controllers.notification_controller import NotificationController


class RelationController:
    """师生关系控制器"""

    @staticmethod
    def search_coaches(student_id, keyword='', gender='', coach_level='',
                      sort_by='rating_desc', page=1, per_page=12):
        """
        搜索教练列表

        Args:
            student_id: 学员ID
            keyword: 搜索关键词
            gender: 性别筛选
            coach_level: 教练等级筛选
            sort_by: 排序方式
            page: 页码
            per_page: 每页数量

        Returns:
            tuple: (分页对象, 总数)
        """
        try:
            # 获取学员信息
            student = User.query.get(student_id)
            if not student or not student.is_student():
                return None, 0

            # 基础查询：同校区的活跃教练
            query = User.query.filter(
                User.role == 'coach',
                User.status == 'active',
                User.campus_id == student.campus_id
            )

            # 关键词搜索
            if keyword:
                query = query.filter(
                    or_(
                        User.real_name.contains(keyword),
                        User.bio.contains(keyword),
                        User.experience.contains(keyword)
                    )
                )

            # 性别筛选
            if gender:
                query = query.filter(User.gender == gender)

            # 教练等级筛选
            if coach_level:
                query = query.filter(User.coach_level == coach_level)

            # 排序
            if sort_by == 'rating_desc':
                # 按评分排序（暂时按创建时间，等评价模块完成后更新）
                query = query.order_by(desc(User.created_at))
            elif sort_by == 'rating_asc':
                query = query.order_by(asc(User.created_at))
            elif sort_by == 'rate_asc':
                query = query.order_by(asc(User.hourly_rate))
            elif sort_by == 'rate_desc':
                query = query.order_by(desc(User.hourly_rate))
            elif sort_by == 'experience_desc':
                query = query.order_by(desc(User.created_at))  # 暂时用创建时间代替经验
            elif sort_by == 'name_asc':
                query = query.order_by(asc(User.real_name))
            else:
                query = query.order_by(desc(User.created_at))

            # 分页
            pagination = query.paginate(
                page=page,
                per_page=per_page,
                error_out=False
            )

            return pagination, pagination.total

        except Exception as e:
            current_app.logger.error(f"搜索教练失败: {e}")
            return None, 0

    @staticmethod
    def get_coach_detail(coach_id, student_id=None):
        """
        获取教练详细信息

        Args:
            coach_id: 教练ID
            student_id: 学员ID（可选）

        Returns:
            dict: 教练详细信息
        """
        try:
            coach = User.query.filter_by(
                id=coach_id,
                role='coach',
                status='active'
            ).first()

            if not coach:
                return None

            # 基本信息
            detail = {
                'coach': coach,
                'student_count': 0,
                'total_classes': 0,
                'average_rating': 0.0,
                'total_reviews': 0,
                'can_apply': False,
                'application_status': None,
                'recent_reviews': []
            }

            # 统计信息（暂时使用模拟数据，等预约和评价模块完成后更新）
            detail['student_count'] = coach.student_relations.filter_by(status='approved').count()

            # 检查学员是否可以申请
            if student_id:
                student = User.query.get(student_id)
                if student and student.campus_id == coach.campus_id:
                    # 检查现有关系
                    existing_relation = StudentCoachRelation.query.filter_by(
                        student_id=student_id,
                        coach_id=coach_id
                    ).first()

                    if existing_relation:
                        detail['application_status'] = existing_relation.status
                    else:
                        # 检查学员的教练数量限制（最多2个）
                        current_coaches = student.student_relations.filter_by(
                            status='approved'
                        ).count()
                        detail['can_apply'] = current_coaches < 2

            return detail

        except Exception as e:
            current_app.logger.error(f"获取教练详情失败: {e}")
            return None

    @staticmethod
    def apply_coach(student_id, coach_id, apply_note=''):
        """
        申请选择教练

        Args:
            student_id: 学员ID
            coach_id: 教练ID
            apply_note: 申请说明

        Returns:
            tuple: (成功标志, 错误信息)
        """
        try:
            # 验证学员
            student = User.query.get(student_id)
            if not student or not student.is_student():
                return False, '学员信息无效'

            # 验证教练
            coach = User.query.get(coach_id)
            if not coach or not coach.is_coach() or coach.status != 'active':
                return False, '教练信息无效或教练不可用'

            # 验证同校区
            if student.campus_id != coach.campus_id:
                return False, '只能申请同校区的教练'

            # 检查是否已存在关系
            existing_relation = StudentCoachRelation.query.filter_by(
                student_id=student_id,
                coach_id=coach_id
            ).first()

            if existing_relation:
                if existing_relation.status == 'pending':
                    return False, '已经申请过该教练，请等待审核'
                elif existing_relation.status == 'approved':
                    return False, '您已经是该教练的学员'
                elif existing_relation.status == 'rejected':
                    # 可以重新申请
                    existing_relation.status = 'pending'
                    existing_relation.apply_note = apply_note
                    existing_relation.applied_at = datetime.now()
                    existing_relation.response_note = None
                    existing_relation.responded_at = None

                    db.session.commit()
                    return True, '重新申请成功，请等待教练审核'

            # 检查学员的教练数量限制（最多2个）
            current_coaches = StudentCoachRelation.query.filter_by(
                student_id=student_id,
                status='approved'
            ).count()

            if current_coaches >= 2:
                return False, '每个学员最多只能选择2个教练'

            # 创建新的申请
            relation = StudentCoachRelation(
                student_id=student_id,
                coach_id=coach_id,
                apply_note=apply_note,
                status='pending',
                applied_at=datetime.now()
            )

            db.session.add(relation)
            db.session.commit()

            # 发送师生关系申请通知
            try:
                student = User.query.get(student_id)
                coach = User.query.get(coach_id)

                if student and coach:
                    # 发送关系变更通知
                    NotificationController.send_relation_notification(
                        relation_id=relation.id,
                        student_id=student.id,
                        coach_id=coach.id,
                        action='applied',
                        relation_data={
                            'student_name': student.real_name,
                            'coach_name': coach.real_name,
                            'action_text': '申请',
                            'apply_note': apply_note[:100] + '...' if apply_note and len(apply_note) > 100 else apply_note,
                            'campus_name': coach.campus.name if coach.campus else '未知校区'
                        }
                    )

            except Exception as e:
                # 通知发送失败不应影响申请创建，只记录日志
                current_app.logger.error(f"发送师生关系申请通知失败: {str(e)}")

            return True, '申请提交成功，请等待教练审核'

        except Exception as e:
            db.session.rollback()
            current_app.logger.error(f"申请教练失败: {e}")
            return False, f'申请失败：{str(e)}'

    @staticmethod
    def get_student_coaches(student_id, status='approved'):
        """
        获取学员的教练列表

        Args:
            student_id: 学员ID
            status: 关系状态

        Returns:
            list: 教练关系列表
        """
        try:
            relations = StudentCoachRelation.query.filter_by(
                student_id=student_id,
                status=status
            ).order_by(desc(StudentCoachRelation.applied_at)).all()

            return relations

        except Exception as e:
            current_app.logger.error(f"获取学员教练失败: {e}")
            return []

    @staticmethod
    def get_student_applications(student_id, status=None, page=1, per_page=10):
        """
        获取学员的申请记录

        Args:
            student_id: 学员ID
            status: 申请状态筛选
            page: 页码
            per_page: 每页数量

        Returns:
            tuple: (分页对象, 总数)
        """
        try:
            query = StudentCoachRelation.query.filter_by(student_id=student_id)

            if status:
                query = query.filter_by(status=status)

            query = query.order_by(desc(StudentCoachRelation.applied_at))

            pagination = query.paginate(
                page=page,
                per_page=per_page,
                error_out=False
            )

            return pagination, pagination.total

        except Exception as e:
            current_app.logger.error(f"获取申请记录失败: {e}")
            return None, 0

    @staticmethod
    def cancel_application(student_id, relation_id):
        """
        取消申请

        Args:
            student_id: 学员ID
            relation_id: 关系ID

        Returns:
            tuple: (成功标志, 错误信息)
        """
        try:
            relation = StudentCoachRelation.query.filter_by(
                id=relation_id,
                student_id=student_id,
                status='pending'
            ).first()

            if not relation:
                return False, '申请记录不存在或无法取消'

            db.session.delete(relation)
            db.session.commit()

            return True, '申请已取消'

        except Exception as e:
            db.session.rollback()
            current_app.logger.error(f"取消申请失败: {e}")
            return False, f'取消失败：{str(e)}'

    @staticmethod
    def remove_coach_relation(student_id, relation_id):
        """
        解除师生关系

        Args:
            student_id: 学员ID
            relation_id: 关系ID

        Returns:
            tuple: (成功标志, 错误信息)
        """
        try:
            relation = StudentCoachRelation.query.filter_by(
                id=relation_id,
                student_id=student_id,
                status='approved'
            ).first()

            if not relation:
                return False, '师生关系不存在'

            # 检查是否有进行中的课程
            # TODO: 等预约模块完成后添加检查逻辑

            # 获取相关用户信息（在删除前）
            student = relation.student
            coach = relation.coach

            # 直接删除关系记录（因为数据库结构不支持terminated状态）
            db.session.delete(relation)

            db.session.commit()

            # 发送师生关系解除通知
            try:
                if student and coach:
                    # 发送关系变更通知
                    NotificationController.send_relation_notification(
                        relation_id=relation_id,  # 使用原ID，因为relation已被删除
                        student_id=student.id,
                        coach_id=coach.id,
                        action='terminated_by_student',
                        relation_data={
                            'student_name': student.real_name,
                            'coach_name': coach.real_name,
                            'action_text': '解除（学员发起）',
                            'campus_name': coach.campus.name if coach.campus else '未知校区',
                            'termination_reason': '学员主动解除师生关系'
                        }
                    )

            except Exception as e:
                # 通知发送失败不应影响解除操作，只记录日志
                current_app.logger.error(f"发送师生关系解除通知失败: {str(e)}")

            return True, '师生关系已解除'

        except Exception as e:
            db.session.rollback()
            current_app.logger.error(f"解除师生关系失败: {e}")
            return False, f'解除失败：{str(e)}'

    @staticmethod
    def get_coach_statistics(coach_id):
        """
        获取教练统计信息

        Args:
            coach_id: 教练ID

        Returns:
            dict: 统计信息
        """
        try:
            stats = {
                'total_students': 0,
                'pending_applications': 0,
                'total_classes': 0,
                'average_rating': 0.0,
                'total_earnings': Decimal('0.00'),
                'response_rate': 0.0
            }

            coach = User.query.get(coach_id)
            if not coach or not coach.is_coach():
                return stats

            # 学员统计 - 直接使用数据库查询替代关系属性
            stats['total_students'] = StudentCoachRelation.query.filter_by(
                coach_id=coach_id,
                status='approved'
            ).count()
            stats['pending_applications'] = StudentCoachRelation.query.filter_by(
                coach_id=coach_id,
                status='pending'
            ).count()

            # 响应率计算 - 直接使用数据库查询替代关系属性
            total_applications = StudentCoachRelation.query.filter_by(coach_id=coach_id).count()
            responded_applications = StudentCoachRelation.query.filter(
                StudentCoachRelation.coach_id == coach_id,
                StudentCoachRelation.status.in_(['approved', 'rejected'])
            ).count()

            if total_applications > 0:
                stats['response_rate'] = (responded_applications / total_applications) * 100

            # TODO: 等预约和评价模块完成后添加课程和收入统计

            return stats

        except Exception as e:
            current_app.logger.error(f"获取教练统计失败: {e}")
            return {
                'total_students': 0,
                'pending_applications': 0,
                'total_classes': 0,
                'average_rating': 0.0,
                'total_earnings': Decimal('0.00'),
                'response_rate': 0.0
            }

    @staticmethod
    def get_coach_search_summary(campus_id):
        """
        获取教练搜索汇总信息

        Args:
            campus_id: 校区ID

        Returns:
            dict: 汇总信息
        """
        try:
            summary = {
                'total_coaches': 0,
                'available_coaches': 0,
                'senior_coaches': 0,
                'middle_coaches': 0,
                'junior_coaches': 0,
                'male_coaches': 0,
                'female_coaches': 0,
                'avg_hourly_rate': Decimal('0.00')
            }

            if not campus_id:
                return summary

            coaches = User.query.filter_by(
                role='coach',
                status='active',
                campus_id=campus_id
            ).all()

            summary['total_coaches'] = len(coaches)
            summary['available_coaches'] = len(coaches)  # 暂时都算可用

            # 按等级统计
            for coach in coaches:
                if coach.coach_level == 'senior':
                    summary['senior_coaches'] += 1
                elif coach.coach_level == 'middle':
                    summary['middle_coaches'] += 1
                else:
                    summary['junior_coaches'] += 1

                # 按性别统计
                if coach.gender == 'male':
                    summary['male_coaches'] += 1
                elif coach.gender == 'female':
                    summary['female_coaches'] += 1

            # 平均课时费
            total_rate = sum(coach.hourly_rate or Decimal('0') for coach in coaches)
            if len(coaches) > 0:
                summary['avg_hourly_rate'] = total_rate / len(coaches)

            return summary

        except Exception as e:
            current_app.logger.error(f"获取教练汇总失败: {e}")
            return {
                'total_coaches': 0,
                'available_coaches': 0,
                'senior_coaches': 0,
                'middle_coaches': 0,
                'junior_coaches': 0,
                'male_coaches': 0,
                'female_coaches': 0,
                'avg_hourly_rate': Decimal('0.00')
            }

    # =========================== 教练端方法 ===========================

    @staticmethod
    def get_coach_applications(coach_id, status=None, page=1, per_page=10):
        """
        获取教练收到的学员申请列表

        Args:
            coach_id: 教练ID
            status: 申请状态筛选
            page: 页码
            per_page: 每页数量

        Returns:
            tuple: (分页对象, 总数)
        """
        try:
            query = StudentCoachRelation.query.filter_by(coach_id=coach_id)

            if status:
                query = query.filter_by(status=status)

            query = query.order_by(desc(StudentCoachRelation.applied_at))

            pagination = query.paginate(
                page=page,
                per_page=per_page,
                error_out=False
            )

            return pagination, pagination.total

        except Exception as e:
            current_app.logger.error(f"获取教练申请失败: {e}")
            return None, 0

    @staticmethod
    def approve_application(coach_id, relation_id, action, response_note=''):
        """
        审核学员申请

        Args:
            coach_id: 教练ID
            relation_id: 关系ID
            action: 操作类型 ('approve' 或 'reject')
            response_note: 回复说明

        Returns:
            tuple: (成功标志, 错误信息)
        """
        try:
            relation = StudentCoachRelation.query.filter_by(
                id=relation_id,
                coach_id=coach_id,
                status='pending'
            ).first()

            if not relation:
                return False, '申请记录不存在或已被处理'

            if action == 'approve':
                # 检查教练的学员数量限制（假设每个教练最多50个学员）
                current_students = StudentCoachRelation.query.filter_by(
                    coach_id=coach_id,
                    status='approved'
                ).count()

                if current_students >= 50:
                    return False, '您的学员数量已达上限，无法接受更多申请'

                relation.status = 'approved'
                relation.response_note = response_note or '欢迎成为我的学员！'

            elif action == 'reject':
                relation.status = 'rejected'
                relation.response_note = response_note or '很抱歉，暂时无法接受您的申请'

            else:
                return False, '无效的操作类型'

            relation.responded_at = datetime.now()

            db.session.commit()

            # 发送师生关系审核通知
            try:
                student = relation.student
                coach = relation.coach

                if student and coach:
                    # 发送关系变更通知
                    NotificationController.send_relation_notification(
                        relation_id=relation.id,
                        student_id=student.id,
                        coach_id=coach.id,
                        action='approved' if action == 'approve' else 'rejected',
                        relation_data={
                            'student_name': student.real_name,
                            'coach_name': coach.real_name,
                            'action_text': '通过' if action == 'approve' else '拒绝',
                            'response_note': response_note[:100] + '...' if response_note and len(response_note) > 100 else response_note,
                            'campus_name': coach.campus.name if coach.campus else '未知校区'
                        }
                    )

            except Exception as e:
                # 通知发送失败不应影响审核操作，只记录日志
                current_app.logger.error(f"发送师生关系审核通知失败: {str(e)}")

            action_text = '通过' if action == 'approve' else '拒绝'
            return True, f'申请已{action_text}'

        except Exception as e:
            db.session.rollback()
            current_app.logger.error(f"审核申请失败: {e}")
            return False, f'审核失败：{str(e)}'

    @staticmethod
    def get_coach_students(coach_id, status='approved', search_keyword='', page=1, per_page=12):
        """
        获取教练的学员列表

        Args:
            coach_id: 教练ID
            status: 关系状态
            search_keyword: 搜索关键词
            page: 页码
            per_page: 每页数量

        Returns:
            tuple: (分页对象, 总数)
        """
        try:
            query = StudentCoachRelation.query.filter_by(
                coach_id=coach_id,
                status=status
            )

            # 关键词搜索
            if search_keyword:
                query = query.join(User, StudentCoachRelation.student_id == User.id).filter(
                    or_(
                        User.real_name.contains(search_keyword),
                        User.phone.contains(search_keyword)
                    )
                )

            query = query.order_by(desc(StudentCoachRelation.responded_at))

            pagination = query.paginate(
                page=page,
                per_page=per_page,
                error_out=False
            )

            return pagination, pagination.total

        except Exception as e:
            current_app.logger.error(f"获取教练学员失败: {e}")
            return None, 0

    @staticmethod
    def get_student_detail_for_coach(coach_id, student_id):
        """
        获取学员详细信息（教练视角）

        Args:
            coach_id: 教练ID
            student_id: 学员ID

        Returns:
            dict: 学员详细信息
        """
        try:
            # 验证师生关系
            relation = StudentCoachRelation.query.filter_by(
                coach_id=coach_id,
                student_id=student_id,
                status='approved'
            ).first()

            if not relation:
                return None

            student = relation.student
            if not student:
                return None

            detail = {
                'student': student,
                'relation': relation,
                'total_classes': 0,  # 暂时使用模拟数据
                'completed_classes': 0,
                'upcoming_classes': 0,
                'total_hours': 0.0,
                'average_rating': 0.0,
                'last_class_date': None,
                'learning_progress': [],
                'attendance_rate': 0.0,
                'payment_status': 'good'  # good, warning, overdue
            }

            # TODO: 等预约和评价模块完成后添加真实数据

            return detail

        except Exception as e:
            current_app.logger.error(f"获取学员详情失败: {e}")
            return None

    @staticmethod
    def remove_student(coach_id, relation_id):
        """
        教练解除师生关系

        Args:
            coach_id: 教练ID
            relation_id: 关系ID

        Returns:
            tuple: (成功标志, 错误信息)
        """
        try:
            relation = StudentCoachRelation.query.filter_by(
                id=relation_id,
                coach_id=coach_id,
                status='approved'
            ).first()

            if not relation:
                return False, '师生关系不存在'

            # 检查是否有进行中的课程
            # TODO: 等预约模块完成后添加检查逻辑

            # 获取相关用户信息（在删除前）
            student = relation.student
            coach = relation.coach

            # 直接删除关系记录（因为数据库结构不支持terminated状态）
            db.session.delete(relation)

            db.session.commit()

            # 发送师生关系解除通知
            try:
                if student and coach:
                    # 发送关系变更通知
                    NotificationController.send_relation_notification(
                        relation_id=relation_id,  # 使用原ID，因为relation已被删除
                        student_id=student.id,
                        coach_id=coach.id,
                        action='terminated_by_coach',
                        relation_data={
                            'student_name': student.real_name,
                            'coach_name': coach.real_name,
                            'action_text': '解除（教练发起）',
                            'campus_name': coach.campus.name if coach.campus else '未知校区',
                            'termination_reason': '教练主动解除师生关系'
                        }
                    )

            except Exception as e:
                # 通知发送失败不应影响解除操作，只记录日志
                current_app.logger.error(f"发送师生关系解除通知失败: {str(e)}")

            return True, '师生关系已解除'

        except Exception as e:
            db.session.rollback()
            current_app.logger.error(f"解除师生关系失败: {e}")
            return False, f'解除失败：{str(e)}'

    @staticmethod
    def get_coach_dashboard_stats(coach_id):
        """
        获取教练仪表板统计信息

        Args:
            coach_id: 教练ID

        Returns:
            dict: 统计信息
        """
        try:
            stats = {
                'pending_applications': 0,
                'total_students': 0,
                'new_applications_today': 0,
                'classes_this_week': 0,
                'recent_applications': [],
                'active_students': []
            }

            # 待处理申请数
            stats['pending_applications'] = StudentCoachRelation.query.filter_by(
                coach_id=coach_id,
                status='pending'
            ).count()

            # 总学员数
            stats['total_students'] = StudentCoachRelation.query.filter_by(
                coach_id=coach_id,
                status='approved'
            ).count()

            # 今日新申请
            today = datetime.now().date()
            stats['new_applications_today'] = StudentCoachRelation.query.filter(
                StudentCoachRelation.coach_id == coach_id,
                StudentCoachRelation.status == 'pending',
                func.date(StudentCoachRelation.applied_at) == today
            ).count()

            # 最近申请
            recent_applications = StudentCoachRelation.query.filter_by(
                coach_id=coach_id,
                status='pending'
            ).order_by(desc(StudentCoachRelation.applied_at)).limit(5).all()
            stats['recent_applications'] = recent_applications

            # 活跃学员（最近有互动的）
            active_students = StudentCoachRelation.query.filter_by(
                coach_id=coach_id,
                status='approved'
            ).order_by(desc(StudentCoachRelation.responded_at)).limit(6).all()
            stats['active_students'] = active_students

            return stats

        except Exception as e:
            current_app.logger.error(f"获取教练统计失败: {e}")
            return {
                'pending_applications': 0,
                'total_students': 0,
                'new_applications_today': 0,
                'classes_this_week': 0,
                'recent_applications': [],
                'active_students': []
            }

    # =========================== 管理员端方法 ===========================

    @staticmethod
    def get_all_relations(campus_id=None, status=None, start_date=None, end_date=None,
                         search_keyword='', page=1, per_page=20):
        """
        获取所有师生关系（管理员视角）

        Args:
            campus_id: 校区ID筛选
            status: 关系状态筛选
            start_date: 开始日期筛选
            end_date: 结束日期筛选
            search_keyword: 搜索关键词
            page: 页码
            per_page: 每页数量

        Returns:
            tuple: (分页对象, 总数)
        """
        try:
            query = StudentCoachRelation.query

            # 校区筛选
            if campus_id:
                query = query.join(User, StudentCoachRelation.coach_id == User.id).filter(
                    User.campus_id == campus_id
                )

            # 状态筛选
            if status:
                query = query.filter(StudentCoachRelation.status == status)

            # 日期筛选
            if start_date:
                try:
                    start_dt = datetime.strptime(start_date, '%Y-%m-%d')
                    query = query.filter(StudentCoachRelation.applied_at >= start_dt)
                except ValueError:
                    pass  # 忽略无效日期格式

            if end_date:
                try:
                    end_dt = datetime.strptime(end_date, '%Y-%m-%d')
                    # 设置为当天结束时间
                    end_dt = end_dt.replace(hour=23, minute=59, second=59)
                    query = query.filter(StudentCoachRelation.applied_at <= end_dt)
                except ValueError:
                    pass  # 忽略无效日期格式

            # 关键词搜索
            if search_keyword:
                query = query.join(User.query.filter(User.id == StudentCoachRelation.student_id), aliased=True).join(
                    User.query.filter(User.id == StudentCoachRelation.coach_id), aliased=True
                ).filter(
                    or_(
                        # 搜索学员姓名
                        User.query.filter(User.id == StudentCoachRelation.student_id).first().real_name.contains(search_keyword),
                        # 搜索教练姓名
                        User.query.filter(User.id == StudentCoachRelation.coach_id).first().real_name.contains(search_keyword)
                    )
                )

            query = query.order_by(desc(StudentCoachRelation.applied_at))

            pagination = query.paginate(
                page=page,
                per_page=per_page,
                error_out=False
            )

            return pagination, pagination.total

        except Exception as e:
            current_app.logger.error(f"获取师生关系失败: {e}")
            return None, 0

    @staticmethod
    def get_relation_detail(relation_id):
        """
        获取师生关系详细信息（管理员视角）

        Args:
            relation_id: 关系ID

        Returns:
            dict: 标准响应格式 {'success': bool, 'data': dict, 'message': str}
        """
        try:
            relation = StudentCoachRelation.query.get(relation_id)
            if not relation:
                return {
                    'success': False,
                    'data': None,
                    'message': '师生关系不存在'
                }

            detail = {
                'relation': relation,
                'student': relation.student,
                'coach': relation.coach,
                'total_classes': 0,  # 暂时使用模拟数据
                'completed_classes': 0,
                'cancelled_classes': 0,
                'total_revenue': Decimal('0.00'),
                'average_rating': 0.0,
                'interaction_history': [],
                'relation_timeline': []
            }

            # TODO: 等预约和评价模块完成后添加真实数据
            # 构建关系时间线
            timeline = []

            if relation.applied_at:
                timeline.append({
                    'type': 'applied',
                    'title': '学员提交申请',
                    'description': f'{relation.student.real_name} 向 {relation.coach.real_name} 提交了选择申请',
                    'timestamp': relation.applied_at,
                    'icon': 'send'
                })

            if relation.responded_at:
                if relation.status == 'approved':
                    timeline.append({
                        'type': 'approved',
                        'title': '申请通过',
                        'description': f'{relation.coach.real_name} 同意了申请，师生关系正式建立',
                        'timestamp': relation.responded_at,
                        'icon': 'check-circle'
                    })
                elif relation.status == 'rejected':
                    timeline.append({
                        'type': 'rejected',
                        'title': '申请被拒绝',
                        'description': f'{relation.coach.real_name} 拒绝了申请',
                        'timestamp': relation.responded_at,
                        'icon': 'x-circle'
                    })

            # 注意：数据库中没有terminated状态，所以不添加terminated时间线

            detail['relation_timeline'] = sorted(timeline, key=lambda x: x['timestamp'])

            return {
                'success': True,
                'data': detail,
                'message': '获取关系详情成功'
            }

        except Exception as e:
            current_app.logger.error(f"获取关系详情失败: {e}")
            return {
                'success': False,
                'data': None,
                'message': f'获取关系详情失败：{str(e)}'
            }



    @staticmethod
    def get_relations_overview():
        """
        获取师生关系概览信息（仪表板用）

        Returns:
            dict: 标准响应格式 {'success': bool, 'data': dict, 'message': str}
        """
        try:
            overview = {
                'total_relations': 0,
                'active_relations': 0,
                'today_new_relations': 0,
                'pending_applications': 0,
                'recent_activities': []
            }

            # 基础统计
            overview['total_relations'] = StudentCoachRelation.query.count()
            overview['active_relations'] = StudentCoachRelation.query.filter_by(status='approved').count()
            overview['pending_applications'] = StudentCoachRelation.query.filter_by(status='pending').count()

            # 今日新建关系
            today = datetime.now().date()
            overview['today_new_relations'] = StudentCoachRelation.query.filter(
                func.date(StudentCoachRelation.responded_at) == today,
                StudentCoachRelation.status == 'approved'
            ).count()

            # 最近活动
            recent_relations = StudentCoachRelation.query.filter(
                StudentCoachRelation.responded_at.isnot(None)
            ).order_by(desc(StudentCoachRelation.responded_at)).limit(10).all()

            activities = []
            for relation in recent_relations:
                if relation.status == 'approved':
                    activities.append({
                        'type': 'approved',
                        'description': f'{relation.student.real_name} 与 {relation.coach.real_name} 建立师生关系',
                        'timestamp': relation.responded_at,
                        'campus': relation.coach.campus.name if relation.coach.campus else '未知校区'
                    })
                elif relation.status == 'rejected':
                    activities.append({
                        'type': 'rejected',
                        'description': f'{relation.coach.real_name} 拒绝了 {relation.student.real_name} 的申请',
                        'timestamp': relation.responded_at,
                        'campus': relation.coach.campus.name if relation.coach.campus else '未知校区'
                    })

            overview['recent_activities'] = activities

            return {
                'success': True,
                'data': overview,
                'message': '获取概览信息成功'
            }

        except Exception as e:
            current_app.logger.error(f"获取关系概览失败: {e}")
            return {
                'success': False,
                'data': {
                    'total_relations': 0,
                    'active_relations': 0,
                    'today_new_relations': 0,
                    'pending_applications': 0,
                    'recent_activities': []
                },
                'message': f'获取概览信息失败：{str(e)}'
            }